package com.fumin.util;

import lombok.extern.slf4j.Slf4j;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.map.ser.impl.SimpleFilterProvider;
import org.codehaus.jackson.type.TypeReference;

/**
 * JSON转化工具类
 * 可以把一个类转化为一个JSON对象,也可以把一个JSON的字符串转化为对应的一个类
 * @Author xiayuxuanmin
 * @Date 2019/10/18
 * @Description
 */
@Slf4j
public class JsonMapper {

    private static ObjectMapper objectMapper = new ObjectMapper();

    static {
        //基本属性设置
        objectMapper.disable(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES);
        objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS,false);
        objectMapper.setFilters(new SimpleFilterProvider().setFailOnUnknownId(false));
        //转化的时候排除为空的字段(比如说转化的时候可能类中有些值没有,这个时候就会被排除掉)
        objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_EMPTY);
    }

    /**
     * 把一个T类型的对象转化为一个字符串
     * @param src 被转化的对象
     * @param <T> src对应的class类型T
     * @return
     */
    public static <T> String obj2String(T src){
        if (src == null) {
            return null;
        }
        try{
            return src instanceof String ? (String)src:objectMapper.writeValueAsString(src);
        }catch(Exception e){
            log.warn("parse object to String exception,T:{},error:{}",src,e);
            return null;
        }
    }

    /**
     * 把一个字符串转化为指定的类独享
     * @param src 需要转化的String字符串
     * @param typeReference
     * @param <T> 转化后的对象的class类型
     * @return
     */
    public static <T> T string2Obj(String src, TypeReference<T> typeReference){
        if (src == null || typeReference == null) {
            return null;
        }
        try{
            return (T)(typeReference.getType().equals(String.class) ? src:objectMapper.readValue(src,typeReference));
        }catch(Exception e){
            log.warn("parse String to Object exception,String:{},TypeReference<T>:{},error:{}",src,typeReference,e);
            return null;
        }
    }
}
